package com.wpp.algorithm.lagou.part1.lesson1;

import java.util.Arrays;

/**
 * @description:
 *      数组 实现整数的数字反转 leetcode 7th
 *      给你一个 32 位的有符号整数 x ，返回将 x 中的数字部分反转后的结果。
 *
 *      如果反转后整数超过 32 位的有符号整数的范围[−2^31,  2^31 − 1] ，就返回 0。
 *
 *      假设环境不允许存储 64 位整数（有符号或无符号）。
 *
 *      来源：力扣（LeetCode）
 *      链接：https://leetcode-cn.com/problems/reverse-integer
 *      著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 *      eg: 123 -> 321
 * @author: WangPengPeng
 * @create: 2022-01-19 21:50
 **/
public class Part1_1 {

    public static void main(String[] args) {
        for (Integer integer : Arrays.asList(123, -123, 120, Integer.MAX_VALUE, Integer.MIN_VALUE)) {
            System.out.println(fun(integer));
        }
        System.out.println("----------------");

        for (Integer integer : Arrays.asList(123, -123, 120, Integer.MAX_VALUE, Integer.MIN_VALUE)) {
            System.out.println(funOfSwapTailAndHead(integer));
        }
        System.out.println("----------------");
        for (Integer integer : Arrays.asList(123, -123, 120, Integer.MAX_VALUE, Integer.MIN_VALUE)) {
            System.out.println(funOfMath(integer));
        }
        System.out.println(subAndSum(234));
        System.out.println(subAndSum(4421));
    }

    /**
     * 暴力解法 -> 逆序输出
     * @param x
     * @return
     */
    private static int fun(int x) {
        if (x == Integer.MAX_VALUE || x == Integer.MIN_VALUE) {
            return 0;
        }
        int mark = x > 0 ? 1 : -1;

        x = x > 0 ? x : -x;
        String str1 = String.valueOf(x);
        char[] chars = str1.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = chars.length - 1; i >= 0; i--) {
            sb.append(chars[i]);
        }

        long l1 = Long.parseLong(sb.toString());
        l1 *= mark;
        if (l1 > Integer.MAX_VALUE || l1 < Integer.MIN_VALUE) {
            return 0;
        }

        return (int) l1;
    }

    /**
     * 首位交换
     * 123 -》 321
     * 1234 -》 4321
     */
    private static int funOfSwapTailAndHead (int x) {
        if (x == Integer.MIN_VALUE || x == Integer.MAX_VALUE ) {
            return 0;
        }
        int mark = x > 0 ? 1 : -1;

        x = x > 0 ? x : -x;
        char[] chars = String.valueOf(x).toCharArray();
        for (int i = 0; i <= chars.length / 2 - 1; i++) {
            char temp = chars[i];
            chars[i] = chars[chars.length - 1 - i];
            chars[chars.length - 1 - i] = temp;
        }
        long l1 = Long.parseLong(String.valueOf(chars));
        l1 *= mark;
        if (l1 > Integer.MAX_VALUE || l1 < Integer.MIN_VALUE) {
            return 0;
        }

        return (int)l1;
    }
    /**
     * 数学解法
     * 123 / 10 = 12
     * 123 % 10 = 3
     * 3*10=30
     *
     * 12 /10 = 1
     * 12 % 10 = 2
     * 30*10 + 2*10=320
     *
     * 1 / 10 = 0
     * 1 % 10 = 1
     * 320 + 1
     */
    private static int funOfMath(int x) {
        if (x == Integer.MAX_VALUE || x == Integer.MIN_VALUE) {
            return 0;
        }
        int mark = x > 0 ? 1 : -1;

        x = x > 0 ? x : -x;

        long ret = 0L;
        int last = 0;
        while (x / 10 != 0) {
            last = x % 10;
            ret = ret * 10 + last * 10;

            x = x / 10;
        }
        if ((last = x % 10) != 0) {
            ret = ret + last;
        }

        ret *= mark;
        if (ret > Integer.MAX_VALUE || ret < Integer.MIN_VALUE) {
            return 0;
        }
        return (int) ret;
    }

    /**
     * 变形
     *    给你一个整数 n，请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差。
     *
     *    示例 1：
     *    输入：n = 234
     *    输出：15
     *    解释：
     *    各位数之积 = 2 * 3 * 4 = 24
     *    各位数之和 = 2 + 3 + 4 = 9
     *    结果 = 24 - 9 = 15
     *
     *    示例 2：
     *    输入：n = 4421
     *    输出：21
     *    解释：
     *    各位数之积 = 4 * 4 * 2 * 1 = 32
     *    各位数之和 = 4 + 4 + 2 + 1 = 11
     *    结果 = 32 - 11 = 21ffff
     *
     *    提示：
     *    1 <= n <= 10^5
     *
     */
    public static int subAndSum(int n) {

        int sub = 1;
        int sum = 0;

        while (n / 10 != 0) {
            sub *= n%10;
            sum += n%10;
            n = n  / 10;
        }
        sub *= n%10;
        sum += n%10;

        return sub - sum;
    }
}
